EC2のメモリ監視をCloudWatch Agentで実施してみた
AWSチームのすずきです。
EC2インスタンス(Amazon Linux 2) のメモリ使用率の監視を行うため、 CloudWatch Agent を設定する機会がありましたので、紹介させていただきます。
環境
以下のEC2インスタンスを対象としました。
- インスタンスタイプ : m5.large
- OS: Amazon Linux 2
- AMI : amzn2-ami-hvm-2.0.20191217.0-x86_64-gp2 (ami-011facbea5ec0363b)
UserData
CloudWatch Agent は、UserDataを利用し、EC2インスタンスの起動時に設定しました。
#cloud-config runcmd: - [ sh, -c, "dd if=/dev/zero of=/swapfile bs=1M count=512" ] - [ sh, -c, "chmod 600 /swapfile; mkswap /swapfile; swapon /swapfile" ] - [ sh, -c, "echo '/swapfile swap swap defaults 0 0' >> /etc/fstab" ] - [ sh, -c, "rpm -Uvh https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm" ] - /opt/aws/amazon-cloudwatch-agent/bin/config-translator --input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml --mode ec2 - /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a start write_files: - content: | { "metrics": { "append_dimensions": { "ImageId": "${aws:ImageId}", "InstanceId": "${aws:InstanceId}", "InstanceType": "${aws:InstanceType}" }, "metrics_collected": { "mem": { "measurement": [ "mem_used_percent" ], "metrics_collection_interval": 60 }, "swap": { "measurement": [ "swap_used_percent" ], "metrics_collection_interval": 60 } } } } mode: '000600' owner: root group: root path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
SWAP設定
メモリ不足の指標とするため小容量のスワップを設置しました。
dd if=/dev/zero of=/swapfile bs=1M count=512 chmod 600 /swapfile; mkswap /swapfile; swapon /swapfile echo '/swapfile swap swap defaults 0 0' >> /etc/fstab
CloudWatch Agent 設定
S3 ダウンロードリンクを利用して、CloudWatch エージェントをインストールしました。
rpm -Uvh https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm
サーバーで CloudWatch エージェントをインストールして実行する
CloudWatch Agent の設定は、JSONからTOML形式に変換して利用しました。
/opt/aws/amazon-cloudwatch-agent/bin/config-translator --input /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json --output /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml --mode ec2
amazon-cloudwatch-agent.json
{ "metrics": { "append_dimensions": { "ImageId": "${!aws:ImageId}", "InstanceId": "${!aws:InstanceId}", "InstanceType": "${!aws:InstanceType}" }, "metrics_collected": { "mem": { "measurement": [ "mem_used_percent" ], "metrics_collection_interval": 60 }, "swap": { "measurement": [ "swap_used_percent" ], "metrics_collection_interval": 60 } } } }
amazon-cloudwatch-agent.toml
[agent] collection_jitter = "0s" debug = false flush_interval = "1s" flush_jitter = "0s" hostname = "" interval = "60s" logfile = "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log" metric_batch_size = 1000 metric_buffer_limit = 10000 omit_hostname = false precision = "" quiet = false round_interval = false [inputs] [[inputs.mem]] fieldpass = ["used_percent"] interval = "60s" [inputs.mem.tags] metricPath = "metrics" [[inputs.swap]] fieldpass = ["used_percent"] interval = "60s" [inputs.swap.tags] metricPath = "metrics" [outputs] [[outputs.cloudwatch]] force_flush_interval = "60s" namespace = "CWAgent" region = "ap-northeast-1" tagexclude = ["host", "metricPath"] [outputs.cloudwatch.tagpass] metricPath = ["metrics"] [processors] [[processors.ec2tagger]] ec2_metadata_tags = ["ImageId", "InstanceId", "InstanceType"] refresh_interval_seconds = "2147483647s" [processors.ec2tagger.tagpass] metricPath = ["metrics"]
IAM
AWS管理ポリシー「CloudWatchAgentServerPolicy」をアタッチしたEC2ロールを用意しました。
- arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
動作確認
監視対象のEC2インスタンスで「stress」コマンドを実行。7〜7.5GBのメモリを消費した状態を発生させました。
sudo rpm -Uvh http://ftp.riken.jp/Linux/dag/redhat/el7/en/x86_64/rpmforge/RPMS/stress-1.0.2-1.el7.rf.x86_64.rpm nohup stress --vm 7 --vm-bytes 1024M --vm-keep & nohup stress -m 2 -q &
Tasks: 105 total, 9 running, 56 sleeping, 0 stopped, 0 zombie %Cpu(s): 60.0 us, 40.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 7865340 total, 329712 free, 7510412 used, 25216 buff/cache KiB Swap: 524284 total, 300548 free, 223736 used. 206404 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 25103 ssm-user 20 0 1056152 1.0g 4 R 20.0 13.3 2:11.10 stress --vm 7 --vm-bytes 1024M --vm-keep 25133 ssm-user 20 0 269720 7304 136 R 20.0 0.1 0:35.66 stress -m 2 -q 25097 ssm-user 20 0 1056152 1.0g 4 R 16.0 13.3 2:11.80 stress --vm 7 --vm-bytes 1024M --vm-keep 25099 ssm-user 20 0 1056152 1.0g 4 R 16.0 13.3 2:03.78 stress --vm 7 --vm-bytes 1024M --vm-keep 25100 ssm-user 20 0 1056152 1.0g 4 R 16.0 13.3 0:30.78 stress --vm 7 --vm-bytes 1024M --vm-keep 433 root 20 0 0 0 0 S 12.0 0.0 0:06.07 [kswapd0] 25101 ssm-user 20 0 1056152 1.0g 4 R 12.0 13.3 0:31.45 stress --vm 7 --vm-bytes 1024M --vm-keep 25132 ssm-user 20 0 269720 168344 136 R 12.0 2.1 0:35.74 stress -m 2 -q 25098 ssm-user 20 0 1056152 985772 4 D 4.0 12.5 0:03.09 stress --vm 7 --vm-bytes 1024M --vm-keep
CloudWatch
指定したインスタンスIDのカスタムメトリックとして、 メモリ使用率が「mem_used_percent」、スワップ使用率が「swap_used_percent」として表示されました。
料金
1台のEC2インスタンスより、2つのカスタムメトリックを1分ごとに30日間連続して登録した場合、CloudWatchで発生するAWS費用は1ドルとなります。
- 最初の 10,000 個のカスタムメトリクス (1 個あたり 0.30 USD) = 2 メトリクス x 0.30 USD = 0.6 USD
- 1,000,001~440,640,000 件までの API リクエストの課金 (1000リクエスト毎に 0.01 USD) = 43,200(分) / 1000 x 0.01 = 0.43USD
まとめ
CloudWatch エージェントを利用する事で、メモリ、スワップ使用率をカスタムメトリックで監視、可視化可能になります。
メモリ不足の傾向が確認出来た場合には、稼働状況の詳細を確認した上でインスタンスタイプのスペックアップやメモリ最適化インスタンス(R5)への変更をご検討ください。
CloudWatch エージェント、メモリ使用率の監視以外に、CPUやディスクなどのカスタムメトリックや、ログファイルのCloudWatchLogsへの集約にも利用できます。
CloudWatch エージェントの導入対象のEC2インスタンスが多数ある場合や、設定変更が予想される場合には、Systems Manager(SSM) もお試しください。
テンプレート
今回利用した環境を再現するCloudFormationテンプレートです。